/**
 * 2017年11月13日
 */
package exp.algorithm.sic.feature;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import exp.algorithm.sic.OctaveSpace;
import exp.algorithm.sic.ScalePeak;
import exp.algorithm.sic.TimeSeries;

/**
 * 分段支持
 * @author Alex
 *
 */

public abstract class SegmentedKeySerieesVectorMaker implements FeatureVectorMaker{
	protected final static int M = OctaveSpace.M;
	protected final static int N = OctaveSpace.N;
	protected final static int NUM = 2*N;
	protected final static int regionLength =	N*M;	
	@Override
	public List<FeatureVector> createFeatureDescriptor(List<ScalePeak> peaks, TimeSeries[] tss) {
		int peakNum = peaks.size();
		if(peakNum == 0) return Collections.emptyList();
		
		float[][][]vals = new float[peakNum][][];
		//点左右各取regionLength长度
		for(int i = 0 ;i<peakNum;i++){
			ScalePeak sp = peaks.get(i);
			//长度,-1之后才是最后一个的索引
			int tsMaxLength = tss[sp.level].data.length;
			int spx = sp.x;
			vals[i] = new float[2*N][3];
			int beginX = -1;
			//如果点索引是spx ,那么长度Lengnth时,索引起点是spx-length+1
			int leftTime = 0;
			if(leftMostIndex(spx)<0){
				int st = spx;
				while(st-M>=-1){st-=M; leftTime++;}
				beginX = st+1;
			}else{
				beginX = leftMostIndex(spx);
				leftTime = N;
			}
			int endX = tsMaxLength;
			//如果点索引是spx ,那么长度Lengnth时,索引终点是spx+length-1
			if(rightMostIndex(spx)>=tsMaxLength){
				int st = spx;
				while(st+M<=tsMaxLength){st+=M;}
				endX = st - 1;
			}else{
				endX = rightMostIndex(spx);
			}
			for(int j = 0 ;j<vals[i].length;j++){
				if(beginX+M>endX) break;
				vals[i][N-leftTime+j]= getStatistics(beginX, M,endX, tss[sp.level]);
				beginX += M;
			}
		}
		ArrayList<FeatureVector> res = new ArrayList<>(vals.length);
		for(float a[][]:vals){
			res.add(DenseFeatureVector.fromFloatArray2D(a));
		}
		return res;
	}

	private int leftMostIndex(int spx){
		return spx-regionLength+1;
		
	}
	private int rightMostIndex(int spx){
		return spx+regionLength-1;
	}
	// segmentLenght一般等于M
	protected  abstract float[] getStatistics(int beginX, int segmentLength,int endX ,TimeSeries ts);

}
